using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;

namespace Microsoft.WowAddonStudio.FrameXml.Components.TypeConverters
{
    /// <summary>
    /// Provides a type converter to convert string objects to and from other representations.
    /// </summary>
    public class ControlSelectorTypeConverter : StringConverter
    {
        private List<string> values;

        /// <summary>
        /// Returns a collection of standard values for the data type this type converter is designed for when provided with a format context.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.ComponentModel.TypeConverter.StandardValuesCollection"></see> that holds a standard set of valid values, or null if the data type does not support a standard set of values.
        /// </returns>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that provides a format context that can be used to extract additional information about the environment from which this converter is invoked. This parameter or properties of this parameter can be null. </param>
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            values = new List<string>();
            var frameControl = context.Instance as IFrameXmlControl;
            if (frameControl != null)
            {
                var service = (IDesignerHost) context.GetService(typeof (IDesignerHost));
                if (service != null)
                {
                    //Add empty item first
                    values.Add(String.Empty);
                    //Add existing controls, except the selected
                    AddControls(service.RootComponent as Control, frameControl);
                }
            }
            return new StandardValuesCollection(values);
        }

        /// <summary>
        /// Inits the controls.
        /// </summary>
        /// <param name="component">The component.</param>
        /// <param name="frameControl">The frame control.</param>
        protected virtual void AddControls(Control component, IFrameXmlControl frameControl)
        {
            if (component == null) return;

            if (component is LayoutFrameControl && frameControl != component)
                values.Add(component.Name);

            if (component.Controls.Count > 0)
            {
                foreach (Control control in component.Controls)
                    AddControls(control, frameControl);
            }
        }

        /// <summary>
        /// Returns whether this object supports a standard set of values that can be picked from a list, using the specified context.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
        /// <returns>
        /// true if <see cref="M:System.ComponentModel.TypeConverter.GetStandardValues"/> should be called to find a common set of values the object supports; otherwise, false.
        /// </returns>
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
    }
}